package com.sharecode.stock.strategy;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.sharecode.stock.strategy.vo.Energy;
import com.sharecode.stock.strategy.vo.KDJ;
import com.sharecode.stock.strategy.vo.MACD;
import com.sharecode.stock.strategy.vo.StrategyVo;
import com.sharecode.stock.vo.stock.StockHistory;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * 
 * @author Administrator
 *
 */
@Slf4j
public class MacdAndKdjStrategy extends StrategySuper {
	private static final Map<String, Integer> noticeCountMap = new ConcurrentHashMap<>();
	private static final Map<String, Integer> notice_macd_map = new ConcurrentHashMap<>();
	private static final Map<String, Integer> notice_kdj_map = new ConcurrentHashMap<>();

	public static void strategy(StrategyVo vo) {
		try {

			if (checkNoticeCount(vo, noticeCountMap)) {
				return;
			}
			List<Energy> energys = vo.getEnergys();
			if (energys.size() < 3) {
				return;
			}
			Energy energy1 = energys.get(energys.size() - 1);
			Energy energy2 = energys.get(energys.size() - 2);
			Energy energy3 = energys.get(energys.size() - 3);
			List<StockHistory> klines = energy1.getStockHistories();
			if (klines.size() < 2) {
				return;
			}
			if (energy2.getStockHistories().size() < 2 || energy3.getStockHistories().size() < 2) {
				setNoticeCountMap(vo, noticeCountMap);
				return;
			}
			macd(vo);
			kdj(vo);

			String id = getEnergyId(vo);
			if (notice_kdj_map.get(id) == null || notice_macd_map.get(id) == null) {
				return;
			}
			try {
				List<MACD> macd = energy1.getMacds();
				int size = macd.size();
				MACD m1 = macd.get(size - 1);
				MACD m2 = macd.get(size - 2);
				double e1 = m1.getMacd();
				double e2 = m2.getMacd();

				String detail = "组合规则-";

				if (e1 < 0 && e2 < 0) {// 0轴下方
					// 上涨回调，不跌破0轴
					for (int i = 0; i < macd.size(); i++) {
						MACD m = macd.get(i);
						if (m.getDif() < 0 || m.getDea() < 0) {
							return;
						}
					}
					List<MACD> macds = energy3.getMacds();
					for (MACD m : macds) {
						if (m.getDea() > 0 || m.getDif() > 0) {
							return;
						}
					}

					List<StockHistory> histories = vo.getStockHistories();

					List<BigDecimal> avg20 = new ArrayList<>();
					List<BigDecimal> avg60 = new ArrayList<>();

					for (int i = 0; i < size; i++) {
						int hs = histories.size() - i;
						StockHistory history = histories.get(hs - 1);
						BigDecimal low = min(history.getClose(), history.getOpen());
						List<StockHistory> subList = histories.subList(0, hs);
						BigDecimal average = average(subList, 60);
						if (low.doubleValue() < average.doubleValue()) {
							log.info("小于60日均线:{},{}", vo.getCode(), history.getDate());
							return;
						}
						avg60.add(average);
						avg20.add(average(subList, 20));
					}
					//20日均线向上
					for (int i = 0; i < avg20.size() - 1; i++) {
						if (lt(avg20.get(i), avg20.get(i + 1))) {
							return;
						}
					}
					for (int i = 0; i < avg60.size() - 1; i++) {
						if (lt(avg60.get(i), avg60.get(i + 1))) {
							return;
						}
					}

//					StockHistory history = histories.get(histories.size() - 1);
//					BigDecimal low =  min(history.getClose(), history.getOpen());
//					BigDecimal average = average(histories, 60);
//					if (low.doubleValue() < average.doubleValue()) {
//						log.info("小于60日均线:{},{}", vo.getCode(), history.getDate());
//						return;
//					}
					strategy(vo, detail + "买,周期" + vo.getCycle() + "天", noticeCountMap, 2);
				}
			} finally {
				setNoticeCountMap(vo, noticeCountMap);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void macd(StrategyVo vo) {
		String id = getEnergyId(vo);
		if (notice_macd_map.get(id) != null) {
			return;
		}
		List<Energy> energys = vo.getEnergys();
		Energy energy1 = energys.get(energys.size() - 1);
		List<MACD> macd = energy1.getMacds();
		int size = macd.size();
		MACD m1 = macd.get(size - 1);
		MACD m2 = macd.get(size - 2);
		double e1 = m1.getMacd();
		double e2 = m2.getMacd();

		if (Math.abs(e1) >= Math.abs(e2)) {
			return;
		}
		notice_macd_map.put(id, 1);
	}

	private static void kdj(StrategyVo vo) {
		String id = getEnergyId(vo);

		List<KDJ> kdj = vo.getKdj();

		int ki = kdj.size() - 1;

		double j0 = kdj.get(ki).getJ();
		double j1 = kdj.get(ki - 1).getJ();

		double d0 = kdj.get(ki).getD();
		double d1 = kdj.get(ki - 1).getD();

		if (j0 < 50 && j0 > j1 && d0 > d1 && d1 > j1 && d0 < j0) {
//			log.info("金叉");
			notice_kdj_map.put(id, 1);
		} else if (j0 < j1 && d0 < d1 && d1 < j1 && d0 > j0) {
//			log.info("死叉");
			if (notice_kdj_map.get(id) != null) {
				notice_kdj_map.remove(id);
			}
		} else {
			return;
		}
		return;
	}
}
